import { Cartesian3 } from "cesium"

/**
 * 生成三次样条插值曲线
 * @param controlPoints 控制点数组（至少需要2个点）
 * @param segments 每个曲线段的插值点数（默认50）
 * @returns 插值后的路径点数组
 */
export function generateSplineCurve(
  controlPoints: Cartesian3[],
  segments: number = 50,
): Cartesian3[] {
  if (controlPoints.length < 2) {
    throw new Error("At least 2 control points are required")
  }

  // 添加虚拟端点以保证首尾曲线平滑
  const points = [
    controlPoints[0],
    ...controlPoints,
    controlPoints[controlPoints.length - 1],
  ]

  const interpolatedPoints: Cartesian3[] = []

  // Catmull-Rom 插值公式
  const interpolate = (
    p0: Cartesian3,
    p1: Cartesian3,
    p2: Cartesian3,
    p3: Cartesian3,
    t: number,
  ): Cartesian3 => {
    const t2 = t * t
    const t3 = t2 * t

    // 系数矩阵
    const a0 = -0.5 * t3 + t2 - 0.5 * t
    const a1 = 1.5 * t3 - 2.5 * t2 + 1
    const a2 = -1.5 * t3 + 2 * t2 + 0.5 * t
    const a3 = 0.5 * t3 - 0.5 * t2

    // 坐标计算
    const x = a0 * p0.x + a1 * p1.x + a2 * p2.x + a3 * p3.x
    const y = a0 * p0.y + a1 * p1.y + a2 * p2.y + a3 * p3.y
    const z = a0 * p0.z + a1 * p1.z + a2 * p2.z + a3 * p3.z

    return new Cartesian3(x, y, z)
  }

  // 遍历每个控制点区间
  for (let i = 1; i < points.length - 2; i++) {
    const p0 = points[i - 1]
    const p1 = points[i]
    const p2 = points[i + 1]
    const p3 = points[i + 2]

    // 生成每个区间的插值点
    for (let s = 0; s <= segments; s++) {
      const t = s / segments
      const point = interpolate(p0, p1, p2, p3, t)
      interpolatedPoints.push(point)
    }
  }

  return interpolatedPoints
}
